/* ***** BEGIN LICENSE BLOCK *****
 * Version: NPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Netscape Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.mozilla.org/NPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is lutsko.com code.
 *
 * The Initial Developer of the Original Code is  James Lutsko 
 * (jim@lutsko.com http://www.lutsko.com).
 * Portions created by the Initial Developer are Copyright (C) 2003
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the NPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the NPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

package autoschedule;

import java.io.Serializable;
import java.util.Calendar;
import java.util.Date;

import autoteam.Local;
import autoteam.Sports;
import db.DBRecord;

public class Game implements Serializable, Comparable
{
	static final long serialVersionUID = -2677749231603548700L;
	
	private Team t1 = null;
	private Team t2 = null;
	int rank = 0;
	private Date date = null;
	Time time;
	Facility facility = null;
	League league = null;
	private boolean _isScheduled = false;
	private String facilityString = null;
	private boolean _isInterLeague = false;
	private Sports sport;

	

	static Calendar cal = Calendar.getInstance();

	public Game()
	{
		
	}

	public Game(Team _t1, Team _t2, int r, League l)
	{
		t1 = _t1;
		t2 = _t2;
		rank = r;
		league = l;
		_isScheduled = false;
	}

	public Game(Game g)
	{
		t1 = g.t1;
		t2 = g.t2;
		rank = g.rank;
		league = g.league;
		_isScheduled = g._isScheduled;
	}

	public Sports getSport()
	{
		return sport;
	}

	public void setSport(Sports sport)
	{
		this.sport = sport;
	}
	
	public String getMatch()
	{
		if (t1 == null || t2 == null)
			return null;
		String s = "" + t1 + "-" + t2;
		return s;
	}

	public boolean involves(Team t)
	{
		return (t == t1) || (t == t2);
	}

	public boolean isScheduled()
	{
		return _isScheduled;
	}

	public void incrementTotalGames()
	{
		t1.totalGames++;
		t2.totalGames++;
	}

	public void assign()
	{
		t1.addGame(this);
		t2.addGame(this);
	}

	public void setFacility(Facility f)
	{
		facility = f;
	}

	public boolean isInterLeague()
	{
		return _isInterLeague;
	}

	public void setTeam(int pos, Object t)
	{
		if (pos == 0)
		{
			if (t1 != null)
				t1.games.remove(this);
			t1 = (Team) t;
			if (t1 != null)
				t1.addGame(this);
		} else
		{
			if (t2 != null)
				t2.games.remove(this);
			t2 = (Team) t;
			if (t2 != null)
				t2.addGame(this);
		}
		if ((t1 != null && t1._isInterLeague)
				|| (t2 != null && t2._isInterLeague))
			_isInterLeague = true;
		else
			_isInterLeague = false;
	}

	public void setFacilityString(String s)
	{
		facilityString = s;
	}

	public Team getTeam(int i)
	{
		return (i == 1 ? t1 : t2);
	}

	public String getFacilityName()
	{
		return (facility == null ? facilityString : facility.name);
	}

	public Date getDate()
	{
		return (Date) (date == null ? null : date.clone());
	}
	
	/*
	 * Returns the start Date with the correct time
	 */
	public Date getStartDate()
	{
		return correctDate(this.getDate(), this.getTime());
	}
	/*
	 * Returns the end Date with the correct time
	 */
	public Date getEndDate()
	{
		return correctDate(this.getDate(), this.getEndTime());
	}
	
	private static Date correctDate(Date date, Time time)
	{
		try{
		long correctDate = date.getTime();
		long resetTime = 22*60*60000; //1 hour = 60 mins*60000millisec
		correctDate -= resetTime;
		correctDate += (long) time.toMinutes()*60000;
		return new Date(correctDate);
		}
		catch (NullPointerException e){
			System.out.println("Malformed Date");
			System.out.println(e);
			return date;
		}
	}
	
	public Time getTime()
	{
		return time;
	}

	public League getLeague()
	{
		return league;
	}

	public Time getEndTime()
	{
		return time.increment(league.getDuration());
	}

	public int getDayOfYear()
	{
		if (date == null)
			return 500;
		cal.setTime(date);
		return cal.get(cal.DAY_OF_YEAR);
	}

	public int getWeekOfYear()
	{
		cal.setTime(date);
		return cal.get(cal.WEEK_OF_YEAR);
	}

	private void zeroDate()
	{
		cal.setTime(date);
		cal.set(cal.HOUR, 10);
		cal.set(cal.MINUTE, 0);
		cal.set(cal.SECOND, 0);
		cal.set(cal.MILLISECOND, 0);
		date = cal.getTime();
	}

	public void setDate(Date _date)
	{
		date = _date;
		zeroDate();
		if (t1 != null)
			t1.sortGames();
		if (t2 != null)
			t2.sortGames();
	}

	public void setTime(Integer tt)
	{
		if (tt == null)
			time = null;
		else
			time = new Time(tt.intValue());
		if (t1 != null)
			t1.sortGames();
		if (t2 != null)
			t2.sortGames();
	}

	void schedule(Date _date, Time t)
	{
		setDate(_date);
		time = t;
		_isScheduled = true;
	}

	public void unSchedule()
	{
		if (facility != null)
			facility.removeGame(this);
		date = null;
		facility = null;
		time = null;
		_isScheduled = false;
	}

	public void remove()
	{
		unSchedule();
		league.games.remove(this);
		if (facility != null)
			facility.games.remove(this);
		if (t1 != null)
			t1.games.remove(this);
		if (t2 != null)
			t2.games.remove(this);
	}

	public void switchWith(Game g)
	{
		this.facility.replaceGame(this, g);
		g.facility.replaceGame(g, this);

		Date rDate = date;
		Facility rFacility = facility;
		Time rTime = time;
		boolean rIs = _isScheduled;
		int rr = rank;

		date = g.date;
		facility = g.facility;
		time = g.time;
		_isScheduled = g._isScheduled;
		// rank = g.rank;

		g.date = rDate;
		g.facility = rFacility;
		g.time = rTime;
		g._isScheduled = rIs;
		// g.rank = rr;

		this.facility.sortGames();
		this.league.sortGames();
		g.facility.sortGames();
		g.league.sortGames();
	}

	public int compareTo(Object o)
	{
		Game g = (Game) o;
		if (rank == g.rank)
		{
			if (t1 == g.t1)
			{
				if (t2 == g.t2)
					return 0;
				else
					return (t2.num > g.t2.num ? 1 : -1);
			} else
				return (t1.num > g.t1.num ? 1 : -1);
		} else
			return (rank > g.rank ? 1 : -1);
	}

	public String toString()
	{
		String s = getMatch() + " at " + getFacilityName() + ": "
				+ (date == null ? null : Local.format(date)) + " starting at "
				+ (time == null ? "tbd" : time.toString());
		return s;
	}

	public String toLongString()
	{
		String s = (time == null ? "tbd" : time.toString() + " - "
				+ getEndTime().toString())
				+ " " + getMatch(); // league.getName()+ (t1.num+1) + "-" +
									// league.getName() + (t2.num+1);
		return s;
	}

	public DBRecord createRecord()
	{
		DBRecord rec = new DBRecord();
		rec.addField("sport", sport.toString());
		rec.addField("team1", t1.name);
		rec.addField("team2", t2.name);
		rec.addField("location", getFacilityName());
		String dateString = "";
		//TODO
		dateString += date.getYear() + "-" + date.getMonth() + "-" + date.getDay();
		rec.addField("date", dateString);
		rec.addField("time", time.toString());
		return rec;
	}
	
	public static void main(String args[]){
		
	}
}
